package com.sweetcircle.service;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.sweetcircle.domain.dto.MessageSendDto;
import com.sweetcircle.domain.enums.MessageTypeEnum;
import com.sweetcircle.domain.enums.VerifyRegexEnum;
import com.sweetcircle.domain.po.ChatMessage;
import com.sweetcircle.domain.po.ContactApply;
import com.sweetcircle.domain.po.UserContact;
import com.sweetcircle.domain.po.UserInfo;
import com.sweetcircle.domain.vo.ContactApplyVO;
import com.sweetcircle.domain.vo.ResponseVO;
import com.sweetcircle.exception.BusinessException;
import com.sweetcircle.mapper.ChatMessageMapper;
import com.sweetcircle.mapper.UserContactMapper;
import com.sweetcircle.mapper.UserInfoMapper;
import com.sweetcircle.utils.AnanUtils;
import com.sweetcircle.utils.PinyinUtils;
import com.sweetcircle.utils.VerifyUtils;
import com.sweetcircle.websocket.MessageHandler;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;


@Service
public class UserContactServiceImpl extends ServiceImpl<UserContactMapper, UserContact> implements UserContactService {
    @Resource
    private MessageHandler messageHandler;

    @Resource
    private UserInfoMapper userInfoMapper;

    @Resource
    private ContactApplyService contactApplyService;

    @Resource
    private UserContactMapper userContactMapper;

    @Resource
    private ChatMessageMapper chatMessageMapper;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<HashMap<String, Object>> getAllContact(String userId) {
        List<HashMap<String, Object>> res = new ArrayList<>();  // 返回结果

        // 获取联系人列表
        List<UserContact> userContacts = list(new LambdaQueryWrapper<UserContact>()
                .eq(UserContact::getUserId, userId)
                .eq(UserContact::getStatus, 1));
        if (userContacts.isEmpty()) {
            return res;
        }

        // 根据首字母排序用户信息
        HashMap<String, List<UserContact>> stringListMap = PinyinUtils.sortFirstLetterUserInfo(userContacts);
        if (stringListMap == null)
            return res;
        String[] array = stringListMap.keySet().toArray(new String[0]);  //获取stringListMap的所有key
        for (String key : array) {
            HashMap<String, Object> map = new HashMap<>();
            map.put("title", key);
            map.put("value", stringListMap.get(key));
            res.add(map);
        }

//        Collections.sort(res, new Comparator<HashMap<String, Object>>() {
//            @Override
//            public int compare(HashMap<String, Object> o1, HashMap<String, Object> o2) {
//                String o = (String) o1.get("title");
//                String o3 = (String) o2.get("title");
//                int c = o.charAt(0);
//                int c1 = o3.charAt(0);
//
//                return c > c1 ? 1 : -1;
//            }
//        });

        // 排序
        res.sort((o1, o2) -> {
            String o = (String) o1.get("title");
            String o3 = (String) o2.get("title");
            int c = o.charAt(0);
            int c1 = o3.charAt(0);
            return c > c1 ? 1 : -1;
        });

        return res;
    }


    /**
     * 添加联系人 向联系人发送申请
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseVO addContact(ContactApplyVO contactApplyVO) {
        ContactApply contactApply = new ContactApply();
        contactApply.setContactApplyId(AnanUtils.getId());
        // 获取登录用户的用户信息
        UserInfo meUserInfo = userInfoMapper.selectOne(new LambdaQueryWrapper<UserInfo>()
                .eq(UserInfo::getUserId, contactApplyVO.getUserId())
                .eq(UserInfo::getStatus, 1));
        //根据 搜索的邮箱 或者甜蜜账号Id 查询用户信息（要添加的用户）
        UserInfo otherUserInfo = new UserInfo();
        String contactUserId = contactApplyVO.getContactUserId();  // 获取联系人用户id
        // 获取用户信息
        if (VerifyUtils.verify(VerifyRegexEnum.EMAIL, contactUserId)) {  // 如果是邮箱
            otherUserInfo = userInfoMapper.selectOne(new LambdaQueryWrapper<UserInfo>()
                    .eq(UserInfo::getEmail, contactUserId)
                    .eq(UserInfo::getStatus, 1));
        } else if (VerifyUtils.verify(VerifyRegexEnum.ID, contactUserId)) {  // 如果是甜蜜账号ID
            otherUserInfo = userInfoMapper.selectOne(new LambdaQueryWrapper<UserInfo>()
                    .eq(UserInfo::getUserSweetCircleId, contactUserId)
                    .eq(UserInfo::getStatus, 1));
        }
        meUserInfo.setPassword(null);
        otherUserInfo.setPassword(null);
        // 查询是否添加过好友的情况
        // 获取对方的好友信息 查询对方是否添加我为好友
        UserContact otherUserContact = userContactMapper.selectOne(new LambdaQueryWrapper<UserContact>()
                .eq(UserContact::getUserId, otherUserInfo.getUserId())
                .eq(UserContact::getContactUserId, meUserInfo.getUserId())
                .eq(UserContact::getStatus, 1));
        if (otherUserContact != null) {  // 对方没有删除我
            if (otherUserContact.getFriendsCode() == 34) { // 我删除了好友 被好友拉黑了
                throw new BusinessException(903, "对方拒绝你添加好友");
            } else if (otherUserContact.getFriendsCode() == 3 || otherUserInfo.getJoinType() == 0) {  // 我是对方的好友  我讲对方删除了 直接添加好友
                UserContact meNewUserContact = new UserContact(
                        meUserInfo.getUserId(),   // 用户id
                        otherUserInfo.getUserId(),  // 联系人用户id
                        otherUserInfo.getUserSweetCircleId(),  // 联系人用户甜甜圈ID
                        1, // 状态 0:非好友 1:好友 2:已删除好友 3:被好友删除 4:已拉黑好友 5:被好友拉黑 34:被好友删除我已拉黑好友
                        otherUserInfo.getAvatar(),  // 头像文件名
                        otherUserInfo.getNickName(),  // 昵称
                        otherUserInfo.getJoinType(), // 好友加入类型
                        otherUserInfo.getSex(),  // 性别
                        otherUserInfo.getPersonalSignature(),  // 个性签名
                        System.currentTimeMillis(),  // 添加时间
                        otherUserInfo.getAreaName(),  // 地区
                        contactApplyVO.getNoteName(), // 备注名
                       1,0,0,
                        1
                );
                boolean insert = SqlHelper.retBool(userContactMapper.insert(meNewUserContact));
                if (!insert) {
                    throw new BusinessException(400, "添加好友失败");
                } else {
                    return new ResponseVO<UserContact>(201, "添加好友成功");
                }

            }
        } else if (otherUserInfo.getJoinType() == 0) {  // 对方没有我的联系人信息 并且对方的加好友方式是直接添加不需要验证的时候 直接添加双方好友
            UserContact meNewUserContact = new UserContact(
                    meUserInfo.getUserId(),   // 用户id
                    otherUserInfo.getUserId(),  // 联系人用户id
                    otherUserInfo.getUserSweetCircleId(),  // 联系人用户甜甜圈ID
                    1, // 状态 0:非好友 1:好友 2:已删除好友 3:被好友删除 4:已拉黑好友 5:被好友拉黑 34:被好友删除我已拉黑好友
                    otherUserInfo.getAvatar(),  // 头像文件名
                    otherUserInfo.getNickName(),  // 昵称
                    0, // 好友加入类型
                    otherUserInfo.getSex(),  // 性别
                    otherUserInfo.getPersonalSignature(),  // 个性签名
                    System.currentTimeMillis(),  // 添加时间
                    otherUserInfo.getAreaName(),  // 地区
                    contactApplyVO.getNoteName(), // 备注名
                    1,0,0,
                    1
            );
            boolean insert = SqlHelper.retBool(userContactMapper.insert(meNewUserContact));
            if (!insert) {
                throw new BusinessException(400, "添加好友失败 添加对方为我的好友失败");
            }
            UserContact otherNewUserContact = new UserContact(
                    otherUserInfo.getUserId(),
                    meUserInfo.getUserId(),
                    meUserInfo.getUserSweetCircleId(),
                    1,
                    meUserInfo.getAvatar(),
                    meUserInfo.getNickName(),
                    1,
                    meUserInfo.getSex(),
                    meUserInfo.getPersonalSignature(),
                    System.currentTimeMillis(),
                    meUserInfo.getAreaName(),
                    "",
                    1,
                    0,
                    0,
                    1
            );
            boolean insert2 = SqlHelper.retBool(userContactMapper.insert(otherNewUserContact));
            if (!insert2) {
                throw new BusinessException(400, "添加好友失败 添加我为对方的好友失败");
            }
            // 向对方发送消息  添加新的联系人
            MessageSendDto<UserContact> messageSendDto = new MessageSendDto<>();
            messageSendDto.setMessageCode(1);  //发送用户
            messageSendDto.setMessageType(101);  // 更新联系人
            messageSendDto.setSendUserId(meUserInfo.getUserId());
            messageSendDto.setContactId(otherUserInfo.getUserId());
            messageSendDto.setExtendData(otherNewUserContact);
            messageHandler.sendMessage(messageSendDto);
            return new ResponseVO<UserContact>(201, "添加好友成功");
        }

        // 获取我的申请信息

        // 我的申请内容
        HashMap<String, Object> meData = new HashMap<>();
        contactApplyVO.setApplyTime(System.currentTimeMillis());
        contactApplyVO.setStatus(0);
        meData.put("contactApply", contactApplyVO);
        meData.put("contactApplyUserInfo", meUserInfo);
        meData.put("type", "me");
        meData.put("contactUserInfo", otherUserInfo);
        ContactApply meContactContactApply = new ContactApply(
                AnanUtils.getId(),
                meUserInfo.getUserId(),
                otherUserInfo.getUserId(),
                System.currentTimeMillis(),
                0,
                JSON.toJSONString(meData),
                1
        );
        boolean save1 = contactApplyService.saveOrUpdate(meContactContactApply, new LambdaQueryWrapper<ContactApply>()
                .eq(ContactApply::getUserId,  meUserInfo.getUserId())
                .eq(ContactApply::getContactUserId, otherUserInfo.getUserId())
                .eq(ContactApply::getStatus, 1));
        if (!save1) {
            throw new BusinessException(400, "保存我的联系人申请失败");
        }

        HashMap<String, Object> otherData = new HashMap<>();
        contactApplyVO.setApplyTime(System.currentTimeMillis());
        contactApplyVO.setStatus(0);
        otherData.put("contactApply", contactApplyVO);  // 谁发送的申请
        otherData.put("contactApplyUserInfo", meUserInfo);  // 发送申请的用户信息
        otherData.put("type", "other");  //类型 别人添加我
        otherData.put("contactUserInfo", meUserInfo);  // 发送申请的联系人信息
        ContactApply otherContactContactApply = new ContactApply(
                AnanUtils.getId(),
                otherUserInfo.getUserId(),
                meUserInfo.getUserId(),
                System.currentTimeMillis(),
                0,
                JSON.toJSONString(otherData),
                1
        );
        boolean save = contactApplyService.saveOrUpdate(otherContactContactApply, new LambdaQueryWrapper<ContactApply>()
                .eq(ContactApply::getUserId,  otherUserInfo.getUserId())
                .eq(ContactApply::getContactUserId, meUserInfo.getUserId())
                .eq(ContactApply::getStatus, 1));


        if (!save) {
            throw new BusinessException(400, "保存对方的联系人申请失败");
        }
        MessageSendDto<ContactApply> messageSendDto = new MessageSendDto<>();
        messageSendDto.setMessageCode(1);  //发送用户
        messageSendDto.setMessageType(4);  // 联系人申请
        messageSendDto.setSendUserId(meUserInfo.getUserId());
        messageSendDto.setContactId(otherUserInfo.getUserId());
        messageSendDto.setExtendData(otherContactContactApply);
        messageSendDto.setMessageContent("申请添加好友");
        messageSendDto.setSendTime(System.currentTimeMillis());

        messageHandler.sendMessage(messageSendDto);
        return new ResponseVO<ContactApply>(401, "申请发送成功", meContactContactApply);

    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<HashMap<String, Object>> acceptApply(HashMap<String, UserContact> userContact) {
        UserContact userContactA = userContact.get("userContactA");  //
        UserContact userContactB = userContact.get("userContactB");

        // 参数校验 必填字段
        AnanUtils.verifyObjectIsEmpty(userContactA, UserContact.class, new String[]{"all"}, new String[]{"noteName"});
        AnanUtils.verifyObjectIsEmpty(userContactB, UserContact.class, new String[]{"all"}, new String[]{"noteName"});

        // 保存联系人
        boolean b = saveOrUpdate(userContactA);
        if (!b) {
            throw new BusinessException(400, "保存我的联系人失败");
        }
        boolean b1 = saveOrUpdate(userContactB);
        if (!b1) {

            throw new BusinessException(400, "保存对方的联系人失败");
        }

        // 更新联系人申请
        ContactApply one1 = new ContactApply();
        one1.setApplyStatus(1);
        boolean update = contactApplyService.update(one1, new LambdaQueryWrapper<ContactApply>()
                .eq(ContactApply::getUserId, userContactA.getUserId())
                .eq(ContactApply::getStatus, 1)
        );
        if (!update) {
            throw new BusinessException(400, "更新联系人申请失败");
        }
        boolean update2 = contactApplyService.update(one1, new LambdaQueryWrapper<ContactApply>()
                .eq(ContactApply::getUserId, userContactB.getUserId())
                .eq(ContactApply::getStatus, 1)
        );
        if (!update2) {
            throw new BusinessException(400, "更新对方的联系人申请失败");
        }


        //给对方发送消息从新获取联系人
        MessageSendDto<String> messageSendDto = new MessageSendDto<>();
        messageSendDto.setMessageContent("添加好友成功");
        messageSendDto.setContactId(userContactA.getContactUserId());
        messageSendDto.setMessageType(101);
        messageSendDto.setMessageCode(1);
        messageSendDto.setExtendData(userContactA.getUserId());
        messageHandler.sendMessage(messageSendDto);


        List<HashMap<String, Object>> allContact = getAllContact(userContactA.getUserId());
        return allContact;
    }

    /**
     * 删除联系人
     *
     * @param userContact
     * @return boolean
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteContact(UserContact userContact) {
        // 删除我的联系人
        boolean remove = remove(new LambdaQueryWrapper<UserContact>()
                .eq(UserContact::getUserId, userContact.getUserId())
                .eq(UserContact::getContactUserId, userContact.getContactUserId())
                .eq(UserContact::getStatus, 1));
        if (!remove) {
            throw new BusinessException(400, "删除联系人失败");
        }

        boolean chatMessages2 = SqlHelper.retBool(chatMessageMapper.selectCount(new LambdaQueryWrapper<ChatMessage>().eq(ChatMessage::getSessionId, userContact.getContactUserId())));
        if (chatMessages2) {

            boolean remove2 = SqlHelper.retBool(chatMessageMapper.delete(new LambdaQueryWrapper<ChatMessage>().eq(ChatMessage::getSessionId, userContact.getContactUserId())));//删除我发送给对方的消息
            if (!remove2) {
                throw new BusinessException(400, "删除我发送给对方的消息失败");
            }
        }

        UserContact u = getOne(new LambdaQueryWrapper<UserContact>()
                .eq(UserContact::getUserId, userContact.getContactUserId())
                .eq(UserContact::getContactUserId, userContact.getUserId())
                .eq(UserContact::getStatus, 1));


        if(u != null){
            // 更新对方的好友消息  设置朋友状态为 3:被好友删除
            UserContact userContact1 = new UserContact();
            userContact1.setFriendsCode(3);
            boolean update = update(userContact1, new LambdaQueryWrapper<UserContact>()
                    .eq(UserContact::getUserId, userContact.getContactUserId())
                    .eq(UserContact::getContactUserId, userContact.getUserId())
                    .eq(UserContact::getStatus, 1));
            if (!update) {
                throw new BusinessException(400, "更新联系人失败 更新联系人的信息失败");
            }
        }

        // 发送消息给对方 从新获取联系人列表
        MessageSendDto<Object> messageSendDto = new MessageSendDto<>();
        messageSendDto.setMessageCode(1);
        messageSendDto.setSendUserId(userContact.getUserId());
        messageSendDto.setContactId(userContact.getContactUserId());
        messageSendDto.setMessageType(MessageTypeEnum.UPDATE_FRIEND.getType());
        messageHandler.sendMessage(messageSendDto);  // 发送消息告知 联系人信息更新 从新获取联系人

        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<HashMap<String, Object>> joinInBlacklist(UserContact userContact) {


        UserContact userContact1 = new UserContact();
        userContact1.setFriendsCode(4); // 0:非好友 1:好友 2:已删除好友 3:被好友删除 4:已拉黑好友 5:被好友拉黑
        boolean update = update(userContact1, new LambdaQueryWrapper<UserContact>()
                .eq(UserContact::getUserId, userContact.getUserId())
                .eq(UserContact::getContactUserId, userContact.getContactUserId())
                .eq(UserContact::getStatus, 1));
        if (!update) {
            throw new BusinessException(400, "更新联系人失败");
        }
        userContact1.setFriendsCode(5); // 0:非好友 1:好友 2:已删除好友 3:被好友删除 4:已拉黑好友 5:被好友拉黑
        boolean update2 = update(userContact1, new LambdaQueryWrapper<UserContact>()
                .eq(UserContact::getContactUserId, userContact.getUserId())
                .eq(UserContact::getUserId, userContact.getContactUserId())
                .eq(UserContact::getStatus, 1));
        if (!update2) {
            throw new BusinessException(400, "更新联系人失败");
        }
        MessageSendDto messageSendDto = new MessageSendDto<>();
        messageSendDto.setMessageCode(1);
        messageSendDto.setSendUserId(userContact.getUserId());
        messageSendDto.setContactId(userContact.getContactUserId());
        messageSendDto.setMessageType(MessageTypeEnum.UPDATE_FRIEND.getType());
        messageHandler.sendMessage(messageSendDto);  // 发送消息告知 联系人信息更新 从新获取联系人


        List<HashMap<String, Object>> allContact = getAllContact(userContact.getUserId());
        return allContact;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<HashMap<String, Object>> removeBlacklist(UserContact userContact) {

        UserContact userContact1 = new UserContact();
        userContact1.setFriendsCode(1);
        boolean update = update(userContact1, new LambdaQueryWrapper<UserContact>()
                .eq(UserContact::getUserId, userContact.getUserId())
                .eq(UserContact::getContactUserId, userContact.getContactUserId())
                .eq(UserContact::getStatus, 1));
        if (!update) {
            throw new BusinessException(400, "更新联系人失败");
        }
        boolean update2 = update(userContact1, new LambdaQueryWrapper<UserContact>()
                .eq(UserContact::getContactUserId, userContact.getUserId())
                .eq(UserContact::getUserId, userContact.getContactUserId())
                .eq(UserContact::getStatus, 1));
        if (!update2) {
            throw new BusinessException(400, "更新联系人失败");
        }
        MessageSendDto messageSendDto = new MessageSendDto<>();
        messageSendDto.setMessageCode(1);
        messageSendDto.setSendUserId(userContact.getUserId());
        messageSendDto.setContactId(userContact.getContactUserId());
        messageSendDto.setMessageType(MessageTypeEnum.UPDATE_FRIEND.getType());
        messageHandler.sendMessage(messageSendDto);  // 发送消息告知 联系人信息更新 从新获取联系人
        List<HashMap<String, Object>> allContact = getAllContact(userContact.getUserId());
        return allContact;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<HashMap<String, Object>> updateContactInfo(UserContact userContact) {
        UserContact userContact1 = new UserContact();
        userContact1.setSweetCircleAuth(userContact.getSweetCircleAuth());
        userContact1.setSweetCircleStatusA(userContact.getSweetCircleStatusA());
        userContact1.setSweetCircleStatusB(userContact.getSweetCircleStatusB());
        boolean update = update(userContact1, new LambdaQueryWrapper<UserContact>()
                .eq(UserContact::getUserId, userContact.getUserId())
                .eq(UserContact::getContactUserId, userContact.getContactUserId())
                .eq(UserContact::getStatus, 1));
        if (!update) {
            throw new BusinessException(400, "更新联系人失败");
        }
        List<HashMap<String, Object>> allContact = getAllContact(userContact.getUserId());
        return allContact;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<HashMap<String, Object>> updateContactNoteName(UserContact userContact) {
        UserContact userContact1 = new UserContact();
        userContact1.setNoteName(userContact.getNoteName());
        boolean update = update(userContact1, new LambdaQueryWrapper<UserContact>()
                .eq(UserContact::getUserId, userContact.getUserId())
                .eq(UserContact::getContactUserId, userContact.getContactUserId())
                .eq(UserContact::getStatus, 1));
        if (!update) {
            throw new BusinessException(400, "更新联系人备注失败");
        }
        List<HashMap<String, Object>> allContact = getAllContact(userContact.getUserId());
        return allContact;
    }


}




